package com.amkai.aes.webservice.binary.objecthandler.casecosting;

import java.io.Serializable;

import com.amkai.aes.aescommon.casecosting.CaseCostingProvider;
import com.amkai.aes.aescommon.service.binary.job.casecosting.CaseCostingJob;
import com.amkai.aes.aescommon.service.binary.job.casecosting.CaseCostingResult;
import com.amkai.aes.generatedbeans.cdmcasehistory.CdmCaseHistory;
import com.amkai.aes.generatedbeans.organization.Department;
import com.amkai.aes.webservice.binary.objecthandler.diee.AbstractLoggerHandler;
import com.amkai.common.extensions.hibernate.config.SiteManager;
import com.amkai.common.extensions.hibernate.config.manager.SessionManager;
import com.amkai.extensions.server.services.ServerServiceManager;

public class CaseCostingHandler extends AbstractLoggerHandler<CaseCostingJob, Serializable, CaseCostingResult> {

	@Override
	public CaseCostingResult process(CaseCostingJob job, Serializable object) throws Exception {
		CaseCostingResult result = new CaseCostingResult();
		if (job.getKind()!=null) {
			line(job.getKind().name(), true);
			switch (job.getKind()) {
			case LOAD_CASE_COSTING_DATA:
				loadCaseCostingData(job, result);
				break;
			case LOAD_TIME_AND_MATERIAL_WORKSHEET_DATA:
				loadTimeAndPaterialWorksheetData(job, result);
				break;
			case LOAD_TIME_AND_MATERIAL_WORKSHEET_DIFFS:
				loadTimeAndPaterialWorksheetDiffs(job, result);
				break;
			case LOAD_CHARGE_CDM_LOG_ASSOCIATIONS:
				loadChargeCdmLogAssociations(job, result);
				break;
			case LOAD_CHARGE_MAP:
				loadChargeMap(job, result);
				break;
			case LOAD_CDM_LOG_BILLED_STATUS:
				loadCdmLogBilledStatusRows(job, result);
				break;
			case LOAD_CDM_LOG_CHARGE_ASSOCIATIONS:
				loadCdmLogChargeAssociations(job, result);
				break;
			}
			line(job.getKind().name(), false);
		}
		return result;
	}
	
	private final CaseCostingProvider getCaseCostingProvider(CaseCostingJob job) throws Exception {
		SessionManager sm = getSessionManager();
		Department department = sm.get(Department.class, job.getModuleDepartment().getId());
		return ServerServiceManager.getInstance().getCaseCostingProviderService().createCaseCostingProvider(sm, department);
	}
	
	private void loadCaseCostingData(CaseCostingJob job, CaseCostingResult result) throws Exception {
		if (job.getParameter()!=null) {
			result.setCaseCostingData(getCaseCostingProvider(job).getCaseCostingData(job.getParameter()));
		} else {
			error("Case costing parameter is empty.");
		}
	}
	
	private final CdmCaseHistory getCdmCaseHistory(CaseCostingJob job) throws Exception {
		SessionManager sm = getSessionManager();
		if (job.getCdmCaseHistoryId()!=null) {
			CdmCaseHistory cdm = sm.get(CdmCaseHistory.class, job.getCdmCaseHistoryId());
			return cdm;
		} else {
			error("CDM/case history id is empty");
		}
		return null;
	}
	
	private void loadTimeAndPaterialWorksheetData(CaseCostingJob job, CaseCostingResult result) throws Exception {
		CdmCaseHistory cdm = getCdmCaseHistory(job);
		if (cdm!=null) {
			result.setTimeAndMaterialWorksheetData(getCaseCostingProvider(job).getTimeAndPaterialWorksheetData(cdm, job.isIncludePAT(), job.isIncludeRecovery()));
		}
	}
	
	private void loadTimeAndPaterialWorksheetDiffs(CaseCostingJob job, CaseCostingResult result) throws Exception {
		CdmCaseHistory cdm = getCdmCaseHistory(job);
		if (cdm!=null) {
			result.setTimeAndMaterialWorksheetDiffs(getCaseCostingProvider(job).getTimeAndMaterialWorksheetDiffs(cdm, job.isIncludePAT(), job.isIncludeRecovery(), job.getCharges()));
		}
	}
	
	private void loadChargeCdmLogAssociations(CaseCostingJob job, CaseCostingResult result) throws Exception {
		CdmCaseHistory cdm = getCdmCaseHistory(job);
		if (cdm!=null) {
			result.setChargeCdmLogAssociations(getCaseCostingProvider(job).getChargeCdmLogAssociations(cdm, job.isIncludePAT(), job.isIncludeRecovery(), job.getCharges()));
		}
	}
	
	private void loadCdmLogChargeAssociations(CaseCostingJob job, CaseCostingResult result) throws Exception {
		CdmCaseHistory cdm = getCdmCaseHistory(job);
		if (cdm!=null) {
			result.setCdmLogChargeAssociations(getCaseCostingProvider(job).getCdmLogChargeAssociations(cdm, job.isIncludePAT(), job.isIncludeRecovery(), job.getKinds()));
		}
	}
	
	private void loadCdmLogBilledStatusRows(CaseCostingJob job, CaseCostingResult result) throws Exception {
		CdmCaseHistory cdm = getCdmCaseHistory(job);
		if (cdm!=null) {
			result.setCdmLogBilledStatusRows(getCaseCostingProvider(job).getCdmLogBillingStatusRows(cdm, job.isIncludePAT(), job.isIncludeRecovery(), job.getProcedureLogs()));
		}
	}
	
	private void loadChargeMap(CaseCostingJob job, CaseCostingResult result) throws Exception {
		CdmCaseHistory cdm = getCdmCaseHistory(job);
		if (cdm!=null) {
			result.setChargeMap(getCaseCostingProvider(job).getChargeMap(cdm, job.isIncludePAT(), job.isIncludeRecovery(), job.getCharges()));
		}
	}	
	
	private SessionManager getSessionManager() throws Exception {
		return SiteManager.Start();
	}
	
}
